#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
挖掘服务模块
处理过程挖掘算法的执行
"""

import pandas as pd
import pm4py
from pm4py.objects.log.util import dataframe_utils
from pm4py.objects.conversion.log import converter as log_converter
from pm4py.algo.discovery.alpha import algorithm as alpha_miner
from pm4py.algo.discovery.heuristics import algorithm as heuristics_miner
from pm4py.algo.evaluation.replay_fitness import algorithm as replay_fitness_evaluator
from pm4py.algo.evaluation.precision import algorithm as precision_evaluator
from pm4py.algo.evaluation.simplicity import algorithm as simplicity_evaluator

class MiningService:
    """挖掘服务类，处理过程挖掘算法的执行"""
    
    def __init__(self):
        """初始化挖掘服务"""
        self.net = None
        self.initial_marking = None
        self.final_marking = None
    
    def apply_alpha_miner(self, log_df, parameters):
        """应用α算法进行挖掘
        
        Args:
            log_df: 日志DataFrame
            parameters: 算法参数字典
        
        Returns:
            tuple: (Petri网, 初始标记, 最终标记)
        """
        try:
            print("开始执行α算法")  # 调试信息
            print(f"输入参数: {parameters}")  # 调试信息
            
            # 确保日志格式正确
            if isinstance(log_df, pd.DataFrame) and log_df.empty:
                raise ValueError("日志为空")
            
            # 转换为事件日志格式
            if isinstance(log_df, pd.DataFrame):
                # 确保列名正确
                log_df = pm4py.format_dataframe(
                    log_df,
                    case_id='case:concept:name',
                    activity_key='concept:name',
                    timestamp_key='time:timestamp'
                )
                event_log = pm4py.convert_to_event_log(log_df)
            else:
                event_log = log_df
            
            print(f"事件日志预览: {event_log[0] if event_log else 'Empty'}")  # 调试信息
            
            # 设置α算法参数
            alpha_params = {}
            
            # 应用α算法
            self.net, self.initial_marking, self.final_marking = alpha_miner.apply(
                event_log,
                parameters=alpha_params
            )
            
            print("α算法执行完成")  # 调试信息
            return self.net, self.initial_marking, self.final_marking
            
        except Exception as e:
            print(f"α算法执行错误: {str(e)}")  # 调试信息
            raise Exception(f"α算法执行失败: {str(e)}")
    
    def apply_heuristics_miner(self, log_df, parameters):
        """应用启发式挖掘算法
        
        Args:
            log_df: 日志DataFrame
            parameters: 算法参数字典
        
        Returns:
            tuple: (Petri网, 初始标记, 最终标记)
        """
        try:
            print("开始执行启发式挖掘算法")  # 调试信息
            print(f"输入参数: {parameters}")  # 调试信息
            
            # 确保日志格式正确
            if isinstance(log_df, pd.DataFrame) and log_df.empty:
                raise ValueError("日志为空")
            
            # 转换为事件日志格式
            if isinstance(log_df, pd.DataFrame):
                # 确保列名正确
                log_df = pm4py.format_dataframe(
                    log_df,
                    case_id='case:concept:name',
                    activity_key='concept:name',
                    timestamp_key='time:timestamp'
                )
                event_log = pm4py.convert_to_event_log(log_df)
            else:
                event_log = log_df
            
            print(f"事件日志预览: {event_log[0] if event_log else 'Empty'}")  # 调试信息
            
            # 设置算法参数
            heuristics_params = {
                "dependency_thresh": float(parameters.get("event_threshold", 50)) / 100,
                "and_measure_thresh": 0.65,
                "min_act_count": 1,
                "min_dfg_occurrences": 1,
                "dfg_pre_cleaning_noise_thresh": 0.05
            }
            
            print(f"转换后的参数: {heuristics_params}")  # 调试信息
            
            # 应用启发式挖掘算法
            self.net, self.initial_marking, self.final_marking = heuristics_miner.apply(
                event_log, 
                parameters=heuristics_params
            )
            
            print("启发式挖掘算法执行完成")  # 调试信息
            return self.net, self.initial_marking, self.final_marking
            
        except Exception as e:
            print(f"启发式挖掘算法执行错误: {str(e)}")  # 调试信息
            raise Exception(f"启发式挖掘算法执行失败: {str(e)}")
    
    def evaluate_model(self, log_df):
        """评估挖掘的模型
        
        Args:
            log_df: 日志DataFrame
        
        Returns:
            dict: 包含评估指标的字典
        """
        try:
            if self.net is None:
                raise ValueError("没有可评估的模型")
            
            # 转换为事件日志格式
            if isinstance(log_df, pd.DataFrame):
                # 确保列名正确
                log_df = pm4py.format_dataframe(
                    log_df,
                    case_id='case:concept:name',
                    activity_key='concept:name',
                    timestamp_key='time:timestamp'
                )
                event_log = pm4py.convert_to_event_log(log_df)
            else:
                event_log = log_df
            
            # 计算评估指标
            fitness = replay_fitness_evaluator.apply(
                event_log, self.net, self.initial_marking, self.final_marking,
                variant=replay_fitness_evaluator.Variants.TOKEN_BASED
            )
            
            precision = precision_evaluator.apply(
                event_log, self.net, self.initial_marking, self.final_marking,
                variant=precision_evaluator.Variants.ETCONFORMANCE_TOKEN
            )
            
            simplicity = simplicity_evaluator.apply(self.net)
            
            return {
                "fitness": fitness.get("average_trace_fitness", 0.0),
                "precision": precision,
                "simplicity": simplicity
            }
            
        except Exception as e:
            print(f"模型评估错误: {str(e)}")  # 调试信息
            raise Exception(f"模型评估失败: {str(e)}") 